package com.codeoss.framework.data.parser;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.codeoss.framework.data.metadata.Column;
import com.codeoss.framework.data.metadata.Table;
import com.codeoss.framework.data.metadata.TableCRUDRule;
import com.codeoss.framework.data.metadata.TableValidationRule;
import com.codeoss.framework.expression.Expression;
import com.codeoss.framework.expression.ExpressionUtil;
import com.codeoss.framework.util.StringUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

@Component("dataTableParser")
public class TableParser implements ITableParser {
	 @Autowired
	 private IColumnParser dataColumnParser;
	@Override
	public Table parser(IDataParseContext dataParseContext, ObjectNode objectNode) {
		// TODO Auto-generated method stub
		Table table=new Table();
		JsonNode jsonNode=objectNode.get("name");
		if(jsonNode!=null) {
			table.setName(jsonNode.asText());
		}
		
		jsonNode=objectNode.get("tableName");
		if(jsonNode!=null) {
			table.setTableName(jsonNode.asText());
		}
		
		jsonNode=objectNode.get("packageName");
		if(jsonNode!=null) {
			table.setPackageName(jsonNode.asText());
		}
		
		jsonNode=objectNode.get("auto");
		if(jsonNode!=null) {
			table.setAuto(jsonNode.asBoolean());
		}
		
		jsonNode=objectNode.get("abstract");
		if(jsonNode!=null) {
			table.setAbstractTable(jsonNode.asBoolean());
		}
		
		jsonNode=objectNode.get("view");
		if(jsonNode!=null) {
			table.setView(jsonNode.asBoolean());
		}
		
		if(table.isView()) {
			jsonNode=objectNode.get("sql");
			if(jsonNode!=null) {
				table.setSql(jsonNode.asText());
			}
		}
		jsonNode=objectNode.get("extendsTable");
		if(jsonNode!=null) {
			table.setExtendsTable(jsonNode.asText());
		}
		
		jsonNode=objectNode.get("accessType");
		if(jsonNode!=null) {
			String accessType=jsonNode.asText();
			if(!StringUtils.isEmpty(accessType)) {
				table.setAccessType(jsonNode.asText());
			}
		}
		
		dataParseContext.setTable(table);
		
		jsonNode=objectNode.get("columnList");
		if(jsonNode!=null) {
			ArrayNode arrayNode=(ArrayNode)jsonNode;
			for(int i=0;i<arrayNode.size();i++) {
				ObjectNode childObjectNode=(ObjectNode)arrayNode.get(i);
				Column column=dataColumnParser.parser(dataParseContext, childObjectNode);
				table.addColumn(column);
			}
		}
		
		jsonNode = objectNode.get("tableValidationRuleList");
		if (jsonNode != null) {
			ArrayNode arrayNode = (ArrayNode) jsonNode;
			List<TableValidationRule> tableValidationRuleList=new ArrayList<TableValidationRule>();
			table.setTableValidationRuleList(tableValidationRuleList);
			for (int i = 0; i < arrayNode.size(); i++) {
				ObjectNode node = (ObjectNode) arrayNode.get(i);
				TableValidationRule tableValidationRule = new TableValidationRule();
				tableValidationRuleList.add(tableValidationRule);
				
				String validationRuleName = node.get("validationRuleName").asText();
				tableValidationRule.setValidationRuleName(validationRuleName);

				String validationRule = node.get("validationRule").asText();
				Expression expression = ExpressionUtil.convertToExpression(validationRule,
						Expression.EXPRESSION_TYPE_JAVASCRIPT);
				tableValidationRule.setValidationRuleExpression(expression);

				String validationErrorMessage = node.get("validationErrorMessage").asText();
				tableValidationRule.setValidationErrorMessage(validationErrorMessage);
			}
		}
		
		TableCRUDRule tableCRUDRule=new TableCRUDRule();
		table.setTableCRUDRule(tableCRUDRule);
		
		jsonNode = objectNode.get("tableCRUDRule");
		if(jsonNode!=null) {
			JsonNode ruleJsonNode=jsonNode.get("beforeInsert");
			if(ruleJsonNode!=null) {
				String rule=ruleJsonNode.asText();
				if(!StringUtils.isEmpty(rule)) {
					Expression expression=ExpressionUtil.convertToExpression(rule, Expression.EXPRESSION_TYPE_JAVASCRIPT);
					tableCRUDRule.setBeforeInsertExpression(expression);
				}
			}
			
			ruleJsonNode=jsonNode.get("beforeUpdate");
			if(ruleJsonNode!=null) {
				String rule=ruleJsonNode.asText();
				if(!StringUtils.isEmpty(rule)) {
					Expression expression=ExpressionUtil.convertToExpression(rule, Expression.EXPRESSION_TYPE_JAVASCRIPT);
					tableCRUDRule.setBeforeUpdateExpression(expression);
				}
			}
			
			ruleJsonNode=jsonNode.get("beforeDelete");
			if(ruleJsonNode!=null) {
				String rule=ruleJsonNode.asText();
				if(!StringUtils.isEmpty(rule)) {
					Expression expression=ExpressionUtil.convertToExpression(rule, Expression.EXPRESSION_TYPE_JAVASCRIPT);
					tableCRUDRule.setBeforeDeleteExpression(expression);
				}
			}
			
			ruleJsonNode=jsonNode.get("afterInsert");
			if(ruleJsonNode!=null) {
				String rule=ruleJsonNode.asText();
				if(!StringUtils.isEmpty(rule)) {
					Expression expression=ExpressionUtil.convertToExpression(rule, Expression.EXPRESSION_TYPE_JAVASCRIPT);
					tableCRUDRule.setAfterInsertExpression(expression);
				}
			}
			
			ruleJsonNode=jsonNode.get("afterUpdate");
			if(ruleJsonNode!=null) {
				String rule=ruleJsonNode.asText();
				if(!StringUtils.isEmpty(rule)) {
					Expression expression=ExpressionUtil.convertToExpression(rule, Expression.EXPRESSION_TYPE_JAVASCRIPT);
					tableCRUDRule.setAfterUpdateExpression(expression);
				}
			}
			
			ruleJsonNode=jsonNode.get("afterDelete");
			if(ruleJsonNode!=null) {
				String rule=ruleJsonNode.asText();
				if(!StringUtils.isEmpty(rule)) {
					Expression expression=ExpressionUtil.convertToExpression(rule, Expression.EXPRESSION_TYPE_JAVASCRIPT);
					tableCRUDRule.setAfterDeleteExpression(expression);
				}
			}
			
			ruleJsonNode=jsonNode.get("Select");
			if(ruleJsonNode!=null) {
				String rule=ruleJsonNode.asText();
				if(!StringUtils.isEmpty(rule)) {
					Expression expression=ExpressionUtil.convertToExpression(rule, Expression.EXPRESSION_TYPE_JAVASCRIPT);
					tableCRUDRule.setSelectExpression(expression);
				}
			}
		}
		table.build();
		return table;
	}

}
